
package com.kweative.model.column;

import com.kweative.model.Table;
import com.kweative.model.access.ColumnAccessHandler;
import com.kweative.model.column.behaviour.Behaviour;
import com.kweative.model.data.DataProvider;
import com.kweative.model.query.QueryUtil;
import com.kweative.model.sql.SQLDataType;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author henrik
 */
abstract public class Column<F extends Column,T extends Table> implements Cloneable,IColumn<T> {

    private T table;
    private Class dataType;
    private String name = "";

    private ColumnAttribute sqlAttribute = null;
    private ColumnExtra sqlExtra = null;

	private SQLDataType sqlDataType = SQLDataType.VARCHAR;
	private String sqlTypeParms = null;
	private boolean sqlNotNull = true;
	private Object sqlDefault = null;


    private ArrayList<Behaviour> behaviours = new ArrayList<Behaviour>();
    private ColumnAccessHandler access;
    private String alias = null;

	public Column(String name,Class dataType) {
		this.name = name;
        this.dataType = dataType;
    }
    public Column(Class dataType) {
        this.dataType = dataType;
    }
    public void setSQLExtra(ColumnExtra extra) {
        sqlExtra = extra;
    }

	protected void setDataType(Class dataType) {
		this.dataType = dataType;
	}

    public void setSQLAttribute(ColumnAttribute attr) {
        sqlAttribute = attr;
    }

    public boolean hasSQLAttribute(ColumnAttribute attr) {
        return sqlAttribute != null && sqlAttribute.equals(attr);
    }

    public boolean hasSQLExtra(ColumnExtra extra) {
        return sqlExtra != null && sqlExtra.equals(extra);
    }

    public ColumnAttribute getSQLAttribute() {
        return sqlAttribute;
    }

    public ColumnExtra getSQLExtra() {
        return sqlExtra;
    }



	public String getSQLTypeParms() {
		return sqlTypeParms;
	}

	protected void setSQLTypeParms(String sqlTypeParms) {
		this.sqlTypeParms = sqlTypeParms;
	}

	public SQLDataType getSQLDataType() {
		return sqlDataType;
	}

	protected void setSQLDataType(SQLDataType sqlDataType) {
		this.sqlDataType = sqlDataType;
	}

	public Object getSQLDefault() {
		return sqlDefault;
	}

	public void setSQLDefault(Object sqlDefault) {
		this.sqlDefault = sqlDefault;
	}

	public boolean isSQLNotNull() {
		return sqlNotNull;
	}

	public void setSQLNotNull(boolean sqlNotNull) {
		this.sqlNotNull = sqlNotNull;
	}

    public Class getDataType() {
        return dataType;
    }


    public ColumnAccessHandler getAccess() {
        return access;
    }

    public Column setAccess(ColumnAccessHandler access) {
        this.access = access;
        return this;
    }
    public Column addBehaviour(Behaviour behaviour) {
        behaviours.add(behaviour);
        return this;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public T getTable() {
        return table;
    }

    public void setTable(T table) {
        this.table = table;
    }
    public void setAlias(String alias) {
        this.alias = alias;
    }

    public String getAlias() {
        return alias;
    }
    
    /**
     * Clone field to an aliased field
     *
     * @param String alias
     * @return
     */
    public F as(String alias) {
        F c = clone();
        c.setAlias(alias);
        return c;
    }

    @Override
    public F clone() {
        try {
            return (F) super.clone();
        } catch (CloneNotSupportedException ex) {
            Logger.getLogger(Column.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

	public String[] getColumnNames() {
		return new String[]{getName()};
	}
    public String serialize(Object value) {
        return String.valueOf(value);
    }
    public Object unserialize(String value) {
        return dataType.cast(value);
    }

	public Object beforeInsert(Object value) {
		//placeholder
		return value;
	}
	public Object beforeUpdate(Object value) {
		//placeholder
		return value;
	}
}
